export = {}

/** Readonly， Partial和 Pick是同态的，但 Record不是。
 * 因为 Record并不需要输入类型来拷贝属性，所以它不属于同态：*/
type ThreeStringProps = Record<'prop1' | 'prop2' | 'prop3', string> //←例子中输入的`prop1`等组成的联合类型 和Record生成的新类型的结构是不同的 没有形成映射 `'prop1' | 'prop2' | 'prop3'`的类型是其三者之间的一种 而ThreeStringProps是要同时拥有三个属性
/*
type ThreeStringProps = {
  prop1: string;
  prop2: string;
  prop3: string;
}
*/
//非同态类型本质上会创建新的属性，因此它们不会从它处拷贝属性修饰符。
/** 同态？非同态？*/
//TODO
//>https://en.wikipedia.org/wiki/Homomorphism
//同态在维基百科的解释是：两个相同类型的代数结构之间的结构保持映射
//同态映射类型 不会引入新的属性





function mapObject<K extends string | number, T, U>(
  obj: Record<K, T>,
  f: (x: T) => U
): Record<K, U> {
  let res = {} as Record<K, U>;
  for (const key in obj) {
    res[key] = f(obj[key]);
  }
  return res;
}

const names = { 0: "hello", 1: "world", 2: "bye" };
const lengths = mapObject(names, s => s.length); // { 0: 5, 1: 5, 2: 3 }
//↑const lengths: Record<0 | 1 | 2, number>
